from fastapi import APIRouter, HTTPException, Depends
from typing import List, Optional
from sqlalchemy.orm import Session
from ..db import session_scope, Label, Annotation
from ..schemas import ApiResponse, LabelIn, LabelOut

router = APIRouter(prefix="/labels", tags=["labels"])

@router.get("")
def list_labels(project_id: Optional[str] = None):
    """获取标签列表"""
    with session_scope() as s:
        q = s.query(Label)
        if project_id:
            q = q.filter(Label.project_id == project_id)
        labels = q.order_by(Label.sort, Label.name).all()
        data = [
            {
                "id": str(l.id),
                "project_id": str(l.project_id) if l.project_id else None,
                "parent_id": str(l.parent_id) if l.parent_id else None,
                "name": l.name,
                "color": l.color,
                "description": l.description,
                "sort": l.sort,
            }
            for l in labels
        ]
        return {"code": 0, "message": "ok", "data": data}

@router.post("")
def create_label(body: LabelIn):
    """创建新标签"""
    with session_scope() as s:
        # 检查同名标签
        existing = s.query(Label).filter(
            Label.name == body.name,
            Label.parent_id == body.parent_id
        ).first()
        if existing:
            raise HTTPException(status_code=400, detail="同级目录下已存在同名标签")
        
        # 如果指定了父级，检查父级是否存在
        if body.parent_id:
            parent = s.get(Label, body.parent_id)
            if not parent:
                raise HTTPException(status_code=400, detail="指定的父级标签不存在")
        
        item = Label(
            project_id=body.project_id,
            parent_id=body.parent_id,
            name=body.name,
            color=body.color,
            description=body.description,
            sort=body.sort,
        )
        s.add(item)
        s.flush()
        return {"code": 0, "message": "ok", "data": {"id": str(item.id)}}

@router.put("/{label_id}")
def update_label(label_id: str, body: LabelIn):
    """更新标签"""
    with session_scope() as s:
        item: Label | None = s.get(Label, label_id)
        if not item:
            raise HTTPException(status_code=404, detail="标签不存在")
        
        # 检查同名标签（排除自己）
        existing = s.query(Label).filter(
            Label.name == body.name,
            Label.parent_id == body.parent_id,
            Label.id != label_id
        ).first()
        if existing:
            raise HTTPException(status_code=400, detail="同级目录下已存在同名标签")
        
        # 如果指定了父级，检查父级是否存在且不是自己的后代
        if body.parent_id:
            if body.parent_id == label_id:
                raise HTTPException(status_code=400, detail="不能将标签设置为自己的父级")
            
            parent = s.get(Label, body.parent_id)
            if not parent:
                raise HTTPException(status_code=400, detail="指定的父级标签不存在")
            
            # 检查是否会形成循环引用
            def check_circular_reference(current_id, target_parent_id):
                if current_id == target_parent_id:
                    return True
                current = s.get(Label, current_id)
                if current and current.parent_id:
                    return check_circular_reference(current.parent_id, target_parent_id)
                return False
            
            if check_circular_reference(body.parent_id, label_id):
                raise HTTPException(status_code=400, detail="不能设置子孙标签为父级，这会造成循环引用")
        
        item.name = body.name
        item.color = body.color
        item.description = body.description
        item.parent_id = body.parent_id
        item.sort = body.sort
        return {"code": 0, "message": "ok"}

@router.delete("/{label_id}")
def delete_label(label_id: str):
    """删除标签"""
    with session_scope() as s:
        item: Label | None = s.get(Label, label_id)
        if not item:
            raise HTTPException(status_code=404, detail="标签不存在")
        
        # 检查是否有子标签
        children = s.query(Label).filter(Label.parent_id == label_id).count()
        if children > 0:
            raise HTTPException(status_code=400, detail="存在子标签，请先删除子标签")
        
        # 检查是否被注释使用
        annotations = s.query(Annotation).filter(Annotation.label_id == label_id).count()
        if annotations > 0:
            raise HTTPException(status_code=400, detail=f"该标签已被 {annotations} 个注释使用，无法删除")
        
        s.delete(item)
        return {"code": 0, "message": "ok"}

@router.get("/{label_id}")
def get_label(label_id: str):
    """获取单个标签详情"""
    with session_scope() as s:
        item: Label | None = s.get(Label, label_id)
        if not item:
            raise HTTPException(status_code=404, detail="标签不存在")
        
        data = {
            "id": str(item.id),
            "project_id": str(item.project_id) if item.project_id else None,
            "parent_id": str(item.parent_id) if item.parent_id else None,
            "name": item.name,
            "color": item.color,
            "description": item.description,
            "sort": item.sort,
        }
        return {"code": 0, "message": "ok", "data": data}
